package gameEngine.agents.choosingStrategy.representation;

import gameEngine.agents.distrebution.representation.ExponentialRepresentation;
import gameEngine.agents.distrebution.representation.FixedRepresentation;
import gameEngine.agents.distrebution.representation.NormalRepresentation;
import gameEngine.agents.distrebution.representation.UniformRepresentation;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import Data.ConfigurationParameters;

/**
 * @author vladimir && alon
 *	The Class is logicly represent Strategy
 *	The purpos of the class:
 *		Be container of data in ExperimentProperties for Strategy
 *		Functionality for build and open XML data of Strategy 
 */
public abstract class StrategyRepresentation {

	protected String strategyName = null;
	
	public String getStrategyName() {
		return strategyName;
	}
	
	/**
	 * Designed for create element Strategy with
	 *   her data
	 * @return Element
	 */
	public Element getXMLElement(Document doc)
	{
		//create Strategy element with name
		Element strategy = doc.createElement(ConfigurationParameters.Strategy.STRATEGY);
		//name
		Element name = doc.createElement("Name");
		name.appendChild(doc.createTextNode(this.strategyName));
		
		strategy.appendChild(name);
		
		//for more strategies elements
		setExtraElement(doc, strategy);
		
		return strategy;	
	}
	
	public abstract void setExtraElement(Document doc, Element strategy);
	
	
	/**
	 * Create and return Strategy Representation
	 *   after read it from the XML
	 * @param doc
	 * @param strategyElement
	 * @param agRepresentation
	 * @param name
	 * @return
	 */
	public static StrategyRepresentation openXMLElement(Document doc, Element strategyElement)
	{
		StrategyRepresentation strategyRepresentation = null;
		String name = getTagValue("Name", strategyElement);
		
		
		//case the eGreedy	
		if(name.equals(ConfigurationParameters.Strategy.EGREEDY))
		{	
			strategyRepresentation = new EGreedyRepresentation(name);
			//set Extra data from the fields to the strategy
			strategyRepresentation.openExtraStrategyData(doc, strategyElement, strategyRepresentation);
		}
		//case Greedy
		else if(name.equals(ConfigurationParameters.Strategy.GREEDY))
		{
			strategyRepresentation = new GreedyRepresentation(name);
			//set Extra data from the fields to the strategy
			strategyRepresentation.openExtraStrategyData(doc, strategyElement, strategyRepresentation);
			
		}
		//case manual adaptive
		else if(name.equals(ConfigurationParameters.Strategy.MANUAL_ADAPTIVE))
		{
			strategyRepresentation = new ManuallAdaptiveRepresentation(name);
			//set Extra data from the fields to the strategy
			strategyRepresentation.openExtraStrategyData(doc, strategyElement, strategyRepresentation);
		}
		//case Round Robin
		else if(name.equals(ConfigurationParameters.Strategy.ROUND_ROBIN))
		{
			strategyRepresentation  = new RoundRobinRepresentation(name);
			//set Extra data from the fields to the strategy
			strategyRepresentation.openExtraStrategyData(doc, strategyElement, strategyRepresentation);
		}
		//case Select worst
		else if(name.equals(ConfigurationParameters.Strategy.SELECT_WORST))
		{
			strategyRepresentation = new SelectWorstRepresentation(name);
			//set Extra data from the fields to the strategy
			strategyRepresentation.openExtraStrategyData(doc, strategyElement, strategyRepresentation);
		}
		//case Simple random
		else if(name.equals(ConfigurationParameters.Strategy.SIMPLE_RANDOM))
		{
			strategyRepresentation  = new SimpleRandomRepresentation(name);
			//set Extra data from the fields to the strategy
			strategyRepresentation.openExtraStrategyData(doc, strategyElement,strategyRepresentation);
		}
		
		return strategyRepresentation;
	}
	
	/**
	 * Created for case the strategy have more data
	 * @param doc
	 * @param strategyElement
	 */
	public abstract void openExtraStrategyData(Document doc, Element strategyElement, 
							StrategyRepresentation strategyRepresentation);
	
	
	/**
	 * @param sTag tag name
	 * @param eElement
	 * @return return the tag value.
	 */
	 protected static String getTagValue(String sTag, Element eElement) {
		NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
	 
	        Node nValue = (Node) nlList.item(0);
	 
		return nValue.getNodeValue();
	 }
}
